home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
TeX 1995 July
/
TeX CD-ROM July 1995 (Disc 1)(Walnut Creek)(1995).ISO
/
dviware
/
dvipage
/
sample.c
< prev
next >
Wrap
C/C++ Source or Header
|
1992-05-11
|
30KB
|
1,246 lines
/*
* dvipage: DVI Previewer Program for Suns
*
* Neil Hunt (hunt@spar.slb.com)
*
* This program is based, in part, upon the program dvisun,
* distributed by the UnixTeX group, extensively modified by
* Neil Hunt at the Schlumberger Palo Alto Research Laboratories
* of Schlumberger Technologies, Inc.
*
* Copyright (c) 1988 Schlumberger Technologies, Inc 1988.
* Anyone can use this software in any manner they choose,
* including modification and redistribution, provided they make
* no charge for it, and these conditions remain unchanged.
*
* This program is distributed as is, with all faults (if any), and
* without any warranty. No author or distributor accepts responsibility
* to anyone for the consequences of using it, or for whether it serves any
* particular purpose at all, or any other reason.
*
* $Log: sample.c,v $
* Revision 1.1 88/11/28 18:41:24 hunt
* Initial revision
*
* Split out of dvipage.c version 1.4.
*/
#include <stdio.h>
#include <sys/param.h> /* For MAXPATHLEN */
#include <suntool/sunview.h>
#include <suntool/canvas.h>
#include "dvipage.h"
forward struct pixrect * pr_alloc();
forward struct pixrect * pr_free();
forward struct pixrect * pr_check();
forward struct pixrect * pr_link();
forward struct pixrect * pr_sample_4();
forward struct pixrect * pr_sample_34();
forward struct pixrect * pr_sample_3();
forward struct pixrect * pr_sample_2();
forward void pw_cover();
forward void pr_rect();
forward void pw_rect();
/*
* sample_page:
* Filter and sample down page according to current sampling rate,
* and prepare for display.
*/
void
sample_page()
{
#ifdef TIMING
start_time();
#endif TIMING
switch(sampling)
{
default:
case 1:
sample_pr = pr_link(&page_mpr, &sample_mpr);
break;
case 2:
if(! (sample_pr = pr_sample_2(&page_mpr, &sample_mpr)))
message("Out of memory for resampling image");
break;
case 3:
if(! (sample_pr = pr_sample_3(&page_mpr, &sample_mpr)))
message("Out of memory for resampling image");
break;
case 4:
if(! (sample_pr = pr_sample_4(&page_mpr, &sample_mpr)))
message("Out of memory for resampling image");
break;
case 5:
if(! (sample_pr = pr_sample_34(&page_mpr, &sample_mpr)))
message("Out of memory for resampling image");
break;
}
#ifdef TIMING
stop_time("Sampling one page");
#endif TIMING
}
/*
* Here follow some functions to deal with pixrects under the special case
* assumption that they are mem_pixrects, where the mpr_data is part
* of a parent structure.
*/
extern struct pixrectops mem_ops;
/*
* pr_alloc:
* Allocate memory for a pixrect of size w, h, d.
* Returns a pointer to the pixrect structure.
*/
struct pixrect *
pr_alloc(mpr, w, h, d)
struct mem_pixrect *mpr;
int w, h, d;
{
int size;
int linebytes;
short *image;
/*
* Compute the size of memory needed, and alloc it.
*/
linebytes = mpr_linebytes(w, d);
size = linebytes * h;
if(! (image = (short *)malloc(size)))
return (struct pixrect *)NULL;
/*
* Set up the pr.
*/
mpr->mpr_pr.pr_ops = &mem_ops;
mpr->mpr_pr.pr_width = w;
mpr->mpr_pr.pr_height = h;
mpr->mpr_pr.pr_depth = d;
mpr->mpr_pr.pr_data = (caddr_t)&mpr->mpr_data;
/*
* Set up the mpr_data
*/
mpr->mpr_data.md_linebytes = linebytes;
mpr->mpr_data.md_image = image;
mpr->mpr_data.md_offset.x = 0;
mpr->mpr_data.md_offset.y = 0;
mpr->mpr_data.md_primary = TRUE;
mpr->mpr_data.md_flags = 0;
/*
* Return the pr.
*/
return &mpr->mpr_pr;
}
/*
* pr_free:
* Free the memory associated with a pixrect.
* Returns a pointer to no pixrect structure.
*/
struct pixrect *
pr_free(mpr)
struct mem_pixrect *mpr;
{
short *image;
if((image = mpr->mpr_data.md_image))
{
if(mpr->mpr_data.md_primary)
free(image);
mpr->mpr_data.md_image = (short *)NULL;
}
mpr->mpr_pr.pr_width = 0;
mpr->mpr_pr.pr_height = 0;
return (struct pixrect *)NULL;
}
/*
* pr_check:
* Check that a designated pixrect has memory allocated for an image
* of size w, h, d. If not, free any existing memory and allocate
* more memory. This is equivalent to, but much faster than, a
* sequence of
* pr_destroy(mpr);
* mpr = mem_create(w, h, d);
*/
struct pixrect *
pr_check(mpr, w, h, d)
struct mem_pixrect *mpr;
int w, h, d;
{
/*
* If there is an image, check that it is the correct size.
*/
if(mpr->mpr_data.md_image)
{
if(mpr->mpr_pr.pr_width == w &&
mpr->mpr_pr.pr_height == h &&
mpr->mpr_pr.pr_depth == d)
return &mpr->mpr_pr;
(void)pr_free(mpr);
}
return pr_alloc(mpr, w, h, d);
}
/*
* pr_link:
* Link the memory of mpr1 to mpr2, making mpr2 a secondary pixrect.
*/
struct pixrect *
pr_link(mpr1, mpr2)
struct mem_pixrect *mpr1;
struct mem_pixrect *mpr2;
{
/*
* Free the existing memory, if any.
*/
(void)pr_free(mpr2);
/*
* Set up the pr.
*/
mpr2->mpr_pr.pr_ops = &mem_ops;
mpr2->mpr_pr.pr_width = mpr1->mpr_pr.pr_width;
mpr2->mpr_pr.pr_height = mpr1->mpr_pr.pr_height;
mpr2->mpr_pr.pr_depth = mpr1->mpr_pr.pr_depth;
mpr2->mpr_pr.pr_data = (caddr_t)&mpr2->mpr_data;
/*
* Set up the mpr_data
*/
mpr2->mpr_data.md_linebytes = mpr1->mpr_data.md_linebytes;
mpr2->mpr_data.md_image = mpr1->mpr_data.md_image;
mpr2->mpr_data.md_offset.x = mpr1->mpr_data.md_offset.x;
mpr2->mpr_data.md_offset.y = mpr1->mpr_data.md_offset.y;
mpr2->mpr_data.md_primary = FALSE;
mpr2->mpr_data.md_flags = 0;
/*
* Return the pr.
*/
return &mpr2->mpr_pr;
}
/*
* Colour Map Stuff
* ================
*/
#define M4F 0
#define M4T (M4F+16)
#define M3F (M4T+1)
#define M3T (M3F+24)
#define M2F (M3T+1)
#define M2T (M2F+4)
uchar cmap_red[64] =
{
#ifdef NEVER
/* Cmap with GAMMA=2,2,2,20,20,20 */
/* 4x4 from 0 to 16 */
255, 247, 239, 231, 223, 214, 205, 196, 186,
175, 163, 151, 137, 121, 103, 78, 20,
/* 3x3 from 17 to 41 */
255, 250, 244, 239, 234, 229, 223, 217, 211,
205, 199, 192, 186, 179, 171, 163, 155,
146, 137, 127, 115, 103, 87, 67, 20,
/* 2x2 from 42 to 46 */
255, 223, 186, 137, 20,
/* spare */
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
#endif NEVER
/* Cmap with GAMMA=1.3,1.3,1.3,0,0,0 */
/* 4x4 from 0 to 16 */
255, 242, 230, 217, 204, 191, 177, 163, 149,
135, 119, 104, 87, 70, 51, 30, 0,
/* 3x3 from 17 to 41 */
255, 246, 238, 230, 221, 213, 204, 195, 186,
177, 168, 159, 149, 139, 130, 119, 109,
98, 87, 76, 64, 51, 37, 22, 0,
/* 2x2 from 42 to 46 */
255, 204, 149, 87, 0,
/* spare */
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
};
uchar cmap_green[64] =
{
/* 4x4 from 0 to 16 */
255, 242, 230, 217, 204, 191, 177, 163, 149,
135, 119, 104, 87, 70, 51, 30, 0,
/* 3x3 from 17 to 41 */
255, 246, 238, 230, 221, 213, 204, 195, 186,
177, 168, 159, 149, 139, 130, 119, 109,
98, 87, 76, 64, 51, 37, 22, 0,
/* 2x2 from 42 to 46 */
255, 204, 149, 87, 0,
/* spare */
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
};
uchar cmap_blue[64] =
{
/* 4x4 from 0 to 16 */
255, 242, 230, 217, 204, 191, 177, 163, 149,
135, 119, 104, 87, 70, 51, 30, 0,
/* 3x3 from 17 to 41 */
255, 246, 238, 230, 221, 213, 204, 195, 186,
177, 168, 159, 149, 139, 130, 119, 109,
98, 87, 76, 64, 51, 37, 22, 0,
/* 2x2 from 42 to 46 */
255, 204, 149, 87, 0,
/* spare */
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
};
double gamma_red = 2.0;
double gamma_green = 2.0;
double gamma_blue = 2.0;
int min_red = 20;
int min_green = 20;
int min_blue = 20;
forward void make_one_cmap();
void
make_cmap()
{
char *e;
if((e = getenv("DVIPAGE_GAMMA")) == NULL)
return;
min_red = 20;
min_green = 20;
min_blue = 20;
gamma_red = 0.0;
gamma_green = 0.0;
gamma_blue = 0.0;
(void)sscanf(e, " %lf,%lf,%lf,%d,%d,%d ",
&gamma_red, &gamma_green, &gamma_blue,
&min_red, &min_green, &min_blue);
if(gamma_red == 0.0)
gamma_red = 1.3;
if(gamma_green == 0.0)
gamma_green = gamma_red;
if(gamma_blue == 0.0)
gamma_blue = gamma_red;
make_one_cmap(cmap_red, 1.0/gamma_red, min_red);
make_one_cmap(cmap_green, 1.0/gamma_green, min_green);
make_one_cmap(cmap_blue, 1.0/gamma_blue, min_blue);
}
void
make_one_cmap(cmap, power, mn)
uchar cmap[];
double power;
int mn;
{
int i;
/*
* 4x4 cmap.
*/
for(i = M4F; i <= M4T; i++)
cmap[i] = (uchar)(pow((double)(M4T - i) / (M4T - M4F), power)
* (255 - mn) + mn);
/*
* 3x3 cmap.
*/
for(i = M3F; i <= M3T; i++)
cmap[i] = (uchar)(pow((double)(M3T - i) / (M3T - M3F), power)
* (255 - mn) + mn);
/*
* 2x2 cmap.
*/
for(i = M2F; i <= M2T; i++)
cmap[i] = (uchar)(pow((double)(M2T - i) / (M2T - M2F), power)
* (255 - mn) + mn);
cmap[63] = mn;
}
/*
* Tally table used to compute the number of bits in packed words.
* This is used in computing the number of bits in a 4x4 region of
* a packed image.
*
* The packed word is used as an index into this table;
* The most significant 16 bits of the value obtained represent the
* number of bits in the upper half of the index, with each bit counted
* with a weight of 15.
* The least significant 16 bits of the value obtained represent the
* number of bits in the l;ower hald of the index, with each bit counted
* with a weight of 15.
*
* By combining the upper and lower halves in a single word, the values
* for the four vertically adjacent words can be combined with each other
* in a single addition per word, adding simultaneously both the tallies
* for the left and the right halves of the word.
*/
static int tally4[] =
{
0x00000000, 0x00000001, 0x00000001, 0x00000002,
0x00000001, 0x00000002, 0x00000002, 0x00000003,
0x00000001, 0x00000002, 0x00000002, 0x00000003,
0x00000002, 0x00000003, 0x00000003, 0x00000004,
0x00010000, 0x00010001, 0x00010001, 0x00010002,
0x00010001, 0x00010002, 0x00010002, 0x00010003,
0x00010001, 0x00010002, 0x00010002, 0x00010003,
0x00010002, 0x00010003, 0x00010003, 0x00010004,
0x00010000, 0x00010001, 0x00010001, 0x00010002,
0x00010001, 0x00010002, 0x00010002, 0x00010003,
0x00010001, 0x00010002, 0x00010002, 0x00010003,
0x00010002, 0x00010003, 0x00010003, 0x00010004,
0x00020000, 0x00020001, 0x00020001, 0x00020002,
0x00020001, 0x00020002, 0x00020002, 0x00020003,
0x00020001, 0x00020002, 0x00020002, 0x00020003,
0x00020002, 0x00020003, 0x00020003, 0x00020004,
0x00010000, 0x00010001, 0x00010001, 0x00010002,
0x00010001, 0x00010002, 0x00010002, 0x00010003,
0x00010001, 0x00010002, 0x00010002, 0x00010003,
0x00010002, 0x00010003, 0x00010003, 0x00010004,
0x00020000, 0x00020001, 0x00020001, 0x00020002,
0x00020001, 0x00020002, 0x00020002, 0x00020003,
0x00020001, 0x00020002, 0x00020002, 0x00020003,
0x00020002, 0x00020003, 0x00020003, 0x00020004,
0x00020000, 0x00020001, 0x00020001, 0x00020002,
0x00020001, 0x00020002, 0x00020002, 0x00020003,
0x00020001, 0x00020002, 0x00020002, 0x00020003,
0x00020002, 0x00020003, 0x00020003, 0x00020004,
0x00030000, 0x00030001, 0x00030001, 0x00030002,
0x00030001, 0x00030002, 0x00030002, 0x00030003,
0x00030001, 0x00030002, 0x00030002, 0x00030003,
0x00030002, 0x00030003, 0x00030003, 0x00030004,
0x00010000, 0x00010001, 0x00010001, 0x00010002,
0x00010001, 0x00010002, 0x00010002, 0x00010003,
0x00010001, 0x00010002, 0x00010002, 0x00010003,
0x00010002, 0x00010003, 0x00010003, 0x00010004,
0x00020000, 0x00020001, 0x00020001, 0x00020002,
0x00020001, 0x00020002, 0x00020002, 0x00020003,
0x00020001, 0x00020002, 0x00020002, 0x00020003,
0x00020002, 0x00020003, 0x00020003, 0x00020004,
0x00020000, 0x00020001, 0x00020001, 0x00020002,
0x00020001, 0x00020002, 0x00020002, 0x00020003,
0x00020001, 0x00020002, 0x00020002, 0x00020003,
0x00020002, 0x00020003, 0x00020003, 0x00020004,
0x00030000, 0x00030001, 0x00030001, 0x00030002,
0x00030001, 0x00030002, 0x00030002, 0x00030003,
0x00030001, 0x00030002, 0x00030002, 0x00030003,
0x00030002, 0x00030003, 0x00030003, 0x00030004,
0x00020000, 0x00020001, 0x00020001, 0x00020002,
0x00020001, 0x00020002, 0x00020002, 0x00020003,
0x00020001, 0x00020002, 0x00020002, 0x00020003,
0x00020002, 0x00020003, 0x00020003, 0x00020004,
0x00030000, 0x00030001, 0x00030001, 0x00030002,
0x00030001, 0x00030002, 0x00030002, 0x00030003,
0x00030001, 0x00030002, 0x00030002, 0x00030003,
0x00030002, 0x00030003, 0x00030003, 0x00030004,
0x00030000, 0x00030001, 0x00030001, 0x00030002,
0x00030001, 0x00030002, 0x00030002, 0x00030003,
0x00030001, 0x00030002, 0x00030002, 0x00030003,
0x00030002, 0x00030003, 0x00030003, 0x00030004,
0x00040000, 0x00040001, 0x00040001, 0x00040002,
0x00040001, 0x00040002, 0x00040002, 0x00040003,
0x00040001, 0x00040002, 0x00040002, 0x00040003,
0x00040002, 0x00040003, 0x00040003, 0x00040004,
};
/*
* Tally table used to compute the number of bits in packed words.
* This is used in computing the number of bits in a 3x3 region of
* a packed image.
*
* The packed word is used as an index into this table;
* Bits 23..16 of the value obtained represent the number of bits in
* the upper 2.67 bits of the index, with each bit counted with a weight
* of 15. etc. etc.
*
* By combining the three parts in a single word, the values
* for the three vertically adjacent words can be combined with each other
* in a single addition per word, adding simultaneously both the tallies
* for the left and the right halves of the word.
*/
static int tally3[] =
{
0x00000000, 0x00000003, 0x00000003, 0x00000006,
0x00000102, 0x00000105, 0x00000105, 0x00000108,
0x00000300, 0x00000303, 0x00000303, 0x00000306,
0x00000402, 0x00000405, 0x00000405, 0x00000408,
0x00000300, 0x00000303, 0x00000303, 0x00000306,
0x00000402, 0x00000405, 0x00000405, 0x00000408,
0x00000600, 0x00000603, 0x00000603, 0x00000606,
0x00000702, 0x00000705, 0x00000705, 0x00000708,
0x00020100, 0x00020103, 0x00020103, 0x00020106,
0x00020202, 0x00020205, 0x00020205, 0x00020208,
0x00020400, 0x00020403, 0x00020403, 0x00020406,
0x00020502, 0x00020505, 0x00020505, 0x00020508,
0x00020400, 0x00020403, 0x00020403, 0x00020406,
0x00020502, 0x00020505, 0x00020505, 0x00020508,
0x00020700, 0x00020703, 0x00020703, 0x00020706,
0x00020802, 0x00020805, 0x00020805, 0x00020808,
0x00030000, 0x00030003, 0x00030003, 0x00030006,
0x00030102, 0x00030105, 0x00030105, 0x00030108,
0x00030300, 0x00030303, 0x00030303, 0x00030306,
0x00030402, 0x00030405, 0x00030405, 0x00030408,
0x00030300, 0x00030303, 0x00030303, 0x00030306,
0x00030402, 0x00030405, 0x00030405, 0x00030408,
0x00030600, 0x00030603, 0x00030603, 0x00030606,
0x00030702, 0x00030705, 0x00030705, 0x00030708,
0x00050100, 0x00050103, 0x00050103, 0x00050106,
0x00050202, 0x00050205, 0x00050205, 0x00050208,
0x00050400, 0x00050403, 0x00050403, 0x00050406,
0x00050502, 0x00050505, 0x00050505, 0x00050508,
0x00050400, 0x00050403, 0x00050403, 0x00050406,
0x00050502, 0x00050505, 0x00050505, 0x00050508,
0x00050700, 0x00050703, 0x00050703, 0x00050706,
0x00050802, 0x00050805, 0x00050805, 0x00050808,
0x00030000, 0x00030003, 0x00030003, 0x00030006,
0x00030102, 0x00030105, 0x00030105, 0x00030108,
0x00030300, 0x00030303, 0x00030303, 0x00030306,
0x00030402, 0x00030405, 0x00030405, 0x00030408,
0x00030300, 0x00030303, 0x00030303, 0x00030306,
0x00030402, 0x00030405, 0x00030405, 0x00030408,
0x00030600, 0x00030603, 0x00030603, 0x00030606,
0x00030702, 0x00030705, 0x00030705, 0x00030708,
0x00050100, 0x00050103, 0x00050103, 0x00050106,
0x00050202, 0x00050205, 0x00050205, 0x00050208,
0x00050400, 0x00050403, 0x00050403, 0x00050406,
0x00050502, 0x00050505, 0x00050505, 0x00050508,
0x00050400, 0x00050403, 0x00050403, 0x00050406,
0x00050502, 0x00050505, 0x00050505, 0x00050508,
0x00050700, 0x00050703, 0x00050703, 0x00050706,
0x00050802, 0x00050805, 0x00050805, 0x00050808,
0x00060000, 0x00060003, 0x00060003, 0x00060006,
0x00060102, 0x00060105, 0x00060105, 0x00060108,
0x00060300, 0x00060303, 0x00060303, 0x00060306,
0x00060402, 0x00060405, 0x00060405, 0x00060408,
0x00060300, 0x00060303, 0x00060303, 0x00060306,
0x00060402, 0x00060405, 0x00060405, 0x00060408,
0x00060600, 0x00060603, 0x00060603, 0x00060606,
0x00060702, 0x00060705, 0x00060705, 0x00060708,
0x00080100, 0x00080103, 0x00080103, 0x00080106,
0x00080202, 0x00080205, 0x00080205, 0x00080208,
0x00080400, 0x00080403, 0x00080403, 0x00080406,
0x00080502, 0x00080505, 0x00080505, 0x00080508,
0x00080400, 0x00080403, 0x00080403, 0x00080406,
0x00080502, 0x00080505, 0x00080505, 0x00080508,
0x00080700, 0x00080703, 0x00080703, 0x00080706,
0x00080802, 0x00080805, 0x00080805, 0x00080808,
};
/*
* Tally table used to compute the number of bits in packed words.
* This is used in computing the number of bits in a 2x2 region of
* a packed image.
*
* The packed word is used as an index into this table;
* The most significant 8 bits of the value obtained represent the
* number of bits in the upper half of the index, with each bit counted
* with a weight of 15.
* ...
* The least significant 8 bits of the value obtained represent the
* number of bits in the l;ower hald of the index, with each bit counted
* with a weight of 15.
*
* By combining the four pairs of tallies in a single word, the values
* for the two vertically adjacent words can be combined with each other
* in a single addition per word, adding simultaneously all four tallies
* for the four pairs of the word.
*/
static int tally2[] =
{
0x00000000, 0x00000001, 0x00000001, 0x00000002,
0x00000100, 0x00000101, 0x00000101, 0x00000102,
0x00000100, 0x00000101, 0x00000101, 0x00000102,
0x00000200, 0x00000201, 0x00000201, 0x00000202,
0x00010000, 0x00010001, 0x00010001, 0x00010002,
0x00010100, 0x00010101, 0x00010101, 0x00010102,
0x00010100, 0x00010101, 0x00010101, 0x00010102,
0x00010200, 0x00010201, 0x00010201, 0x00010202,
0x00010000, 0x00010001, 0x00010001, 0x00010002,
0x00010100, 0x00010101, 0x00010101, 0x00010102,
0x00010100, 0x00010101, 0x00010101, 0x00010102,
0x00010200, 0x00010201, 0x00010201, 0x00010202,
0x00020000, 0x00020001, 0x00020001, 0x00020002,
0x00020100, 0x00020101, 0x00020101, 0x00020102,
0x00020100, 0x00020101, 0x00020101, 0x00020102,
0x00020200, 0x00020201, 0x00020201, 0x00020202,
0x01000000, 0x01000001, 0x01000001, 0x01000002,
0x01000100, 0x01000101, 0x01000101, 0x01000102,
0x01000100, 0x01000101, 0x01000101, 0x01000102,
0x01000200, 0x01000201, 0x01000201, 0x01000202,
0x01010000, 0x01010001, 0x01010001, 0x01010002,
0x01010100, 0x01010101, 0x01010101, 0x01010102,
0x01010100, 0x01010101, 0x01010101, 0x01010102,
0x01010200, 0x01010201, 0x01010201, 0x01010202,
0x01010000, 0x01010001, 0x01010001, 0x01010002,
0x01010100, 0x01010101, 0x01010101, 0x01010102,
0x01010100, 0x01010101, 0x01010101, 0x01010102,
0x01010200, 0x01010201, 0x01010201, 0x01010202,
0x01020000, 0x01020001, 0x01020001, 0x01020002,
0x01020100, 0x01020101, 0x01020101, 0x01020102,
0x01020100, 0x01020101, 0x01020101, 0x01020102,
0x01020200, 0x01020201, 0x01020201, 0x01020202,
0x01000000, 0x01000001, 0x01000001, 0x01000002,
0x01000100, 0x01000101, 0x01000101, 0x01000102,
0x01000100, 0x01000101, 0x01000101, 0x01000102,
0x01000200, 0x01000201, 0x01000201, 0x01000202,
0x01010000, 0x01010001, 0x01010001, 0x01010002,
0x01010100, 0x01010101, 0x01010101, 0x01010102,
0x01010100, 0x01010101, 0x01010101, 0x01010102,
0x01010200, 0x01010201, 0x01010201, 0x01010202,
0x01010000, 0x01010001, 0x01010001, 0x01010002,
0x01010100, 0x01010101, 0x01010101, 0x01010102,
0x01010100, 0x01010101, 0x01010101, 0x01010102,
0x01010200, 0x01010201, 0x01010201, 0x01010202,
0x01020000, 0x01020001, 0x01020001, 0x01020002,
0x01020100, 0x01020101, 0x01020101, 0x01020102,
0x01020100, 0x01020101, 0x01020101, 0x01020102,
0x01020200, 0x01020201, 0x01020201, 0x01020202,
0x02000000, 0x02000001, 0x02000001, 0x02000002,
0x02000100, 0x02000101, 0x02000101, 0x02000102,
0x02000100, 0x02000101, 0x02000101, 0x02000102,
0x02000200, 0x02000201, 0x02000201, 0x02000202,
0x02010000, 0x02010001, 0x02010001, 0x02010002,
0x02010100, 0x02010101, 0x02010101, 0x02010102,
0x02010100, 0x02010101, 0x02010101, 0x02010102,
0x02010200, 0x02010201, 0x02010201, 0x02010202,
0x02010000, 0x02010001, 0x02010001, 0x02010002,
0x02010100, 0x02010101, 0x02010101, 0x02010102,
0x02010100, 0x02010101, 0x02010101, 0x02010102,
0x02010200, 0x02010201, 0x02010201, 0x02010202,
0x02020000, 0x02020001, 0x02020001, 0x02020002,
0x02020100, 0x02020101, 0x02020101, 0x02020102,
0x02020100, 0x02020101, 0x02020101, 0x02020102,
0x02020200, 0x02020201, 0x02020201, 0x02020202,
};
/*
* P_row:
* Access macro for obtaining a pointer to the bytes of a pixrect
* starting at row `row'.
*/
#define P_row(mpr, row) \
(uchar *)((int)((mpr)->mpr_data.md_image) + \
(int)((short)(row) * (short)((mpr)->mpr_data.md_linebytes)));
/*
* pr_sample_4:
* Filter and sample mpr1 on a 4x4 basis into mpr2.
*/
struct pixrect *
pr_sample_4(mpr1, mpr2)
struct mem_pixrect *mpr1;
struct mem_pixrect *mpr2;
{
int cols, rows;
int j;
register uchar *p0; /* a5 */
register uchar *p1; /* a4 */
register uchar *p2; /* a3 */
register uchar *p3; /* a2 */
register uchar *pr;
register uchar *er;
register int tallies; /* d7 */
int line_offset;
cols = mpr1->mpr_pr.pr_width / 4;
rows = mpr1->mpr_pr.pr_height / 4;
if(verbose & DEBUG_IMSIZE)
fprintf(stderr, "pr_sample_4: (%d x %d) -> (%d x %d)\n",
mpr1->mpr_pr.pr_width, mpr1->mpr_pr.pr_height, cols, rows);
/*
* Allocate output image.
*/
if(! pr_check(mpr2, cols, rows, 8))
return (struct pixrect *)NULL;
/*
* Do the sampling.
*/
line_offset = mpr1->mpr_data.md_linebytes;
for(j = 0; j < rows; j++)
{
p0 = P_row(mpr1, j*4);
p1 = p0 + line_offset;
p2 = p1 + line_offset;
p3 = p2 + line_offset;
pr = P_row(mpr2, j);
for(er = pr + cols; pr < er; )
{
/*
* Test for all zero.
if(*p0 == 0 && *p1 == 0 && *p2 == 0 && *p3 == 0)
{
*pr++ = 0;
if(pr >= er)
break;
*pr++ = 0;
}
else
*/
{
tallies =
tally4[*p0] +
tally4[*p1] +
tally4[*p2] +
tally4[*p3];
/*
* High order 4 bits
*/
*pr++ = (tallies >> 16) + M4F;
if(pr >= er)
break;
/*
* Low order 4 bits
*/
*pr++ = tallies + M4F;
}
p0++;
p1++;
p2++;
p3++;
}
}
return &mpr2->mpr_pr;
}
/*
* pr_sample_34:
* Filter and sample mpr1 on a 2.67x4 basis into mpr2.
* Tally count uses M3 table, and gets up to 32 pixels (weighted at 1/3)
* divides by two to index into the 0..16 M4 table.
*/
struct pixrect *
pr_sample_34(mpr1, mpr2)
struct mem_pixrect *mpr1;
struct mem_pixrect *mpr2;
{
int cols, rows;
int j;
register uchar *p0; /* a5 */
register uchar *p1; /* a4 */
register uchar *p2; /* a3 */
register uchar *p3; /* a2 */
register uchar *pr;
register uchar *er;
register int tallies; /* d7 */
int line_offset;
cols = mpr1->mpr_pr.pr_width * 3 / 8;
rows = mpr1->mpr_pr.pr_height / 4;
if(verbose & DEBUG_IMSIZE)
fprintf(stderr, "pr_sample_34: (%d x %d) -> (%d x %d)\n",
mpr1->mpr_pr.pr_width, mpr1->mpr_pr.pr_height, cols, rows);
/*
* Allocate output image.
*/
if(! pr_check(mpr2, cols, rows, 8))
return (struct pixrect *)NULL;
/*
* Do the sampling.
*/
line_offset = mpr1->mpr_data.md_linebytes;
for(j = 0; j < rows; j++)
{
p0 = P_row(mpr1, j*4);
p1 = p0 + line_offset;
p2 = p1 + line_offset;
p3 = p2 + line_offset;
pr = P_row(mpr2, j);
for(er = pr + cols; pr < er; )
{
/*
* Test for all zero.
if(*p0 == 0 && *p1 == 0 && *p2 == 0)
{
*pr++ = 0;
if(pr >= er)
break;
*pr++ = 0;
if(pr >= er)
break;
*pr++ = 0;
}
else
*/
{
tallies =
tally3[*p0] +
tally3[*p1] +
tally3[*p2] +
tally3[*p3];
/*
* High order 3 bits
*/
*pr++ = (tallies >> (16+1)) + M4F;
if(pr >= er)
break;
*pr++ = (tallies >> (8+1)) + M4F;
if(pr >= er)
break;
/*
* Low order 3 bits
*/
*pr++ = (tallies >> 1) + M4F;
}
p0++;
p1++;
p2++;
p3++;
}
}
return &mpr2->mpr_pr;
}
/*
* pr_sample_3:
* Filter and sample mpr1 on a 3x3 basis into mpr2.
* Note that the horizontal sampling is actually 3/8 rather than 1/3.
*/
struct pixrect *
pr_sample_3(mpr1, mpr2)
struct mem_pixrect *mpr1;
struct mem_pixrect *mpr2;
{
int cols, rows;
int j;
register uchar *p0; /* a5 */
register uchar *p1; /* a4 */
register uchar *p2; /* a3 */
register uchar *pr; /* a2 */
register uchar *er;
register int tallies; /* d7 */
int line_offset;
cols = mpr1->mpr_pr.pr_width * 3 / 8;
rows = mpr1->mpr_pr.pr_height / 3;
if(verbose & DEBUG_IMSIZE)
fprintf(stderr, "pr_sample_3: (%d x %d) -> (%d x %d)\n",
mpr1->mpr_pr.pr_width, mpr1->mpr_pr.pr_height, cols, rows);
/*
* Allocate output image.
*/
if(! pr_check(mpr2, cols, rows, 8))
return (struct pixrect *)NULL;
/*
* Do the sampling.
*/
line_offset = mpr1->mpr_data.md_linebytes;
for(j = 0; j < rows; j++)
{
p0 = P_row(mpr1, j*3);
p1 = p0 + line_offset;
p2 = p1 + line_offset;
pr = P_row(mpr2, j);
for(er = pr + cols; pr < er; )
{
/*
* Test for all zero.
if(*p0 == 0 && *p1 == 0 && *p2 == 0)
{
*pr++ = 0;
if(pr >= er)
break;
*pr++ = 0;
if(pr >= er)
break;
*pr++ = 0;
}
else
*/
{
tallies =
tally3[*p0] +
tally3[*p1] +
tally3[*p2];
/*
* High order 3 bits
*/
*pr++ = (tallies >> 16) + M3F;
if(pr >= er)
break;
*pr++ = (tallies >> 8) + M3F;
if(pr >= er)
break;
/*
* Low order 3 bits
*/
*pr++ = tallies + M3F;
}
p0++;
p1++;
p2++;
}
}
return &mpr2->mpr_pr;
}
/*
* pr_sample_2:
* Filter and sample mpr1 on a 2x2 basis into mpr2.
*/
struct pixrect *
pr_sample_2(mpr1, mpr2)
struct mem_pixrect *mpr1;
struct mem_pixrect *mpr2;
{
int cols, rows;
int j;
register uchar *p0; /* a5 */
register uchar *p1; /* a4 */
register uchar *pr; /* a3 */
register uchar *er; /* a2 */
register int tallies; /* d7 */
int line_offset;
cols = mpr1->mpr_pr.pr_width / 2;
rows = mpr1->mpr_pr.pr_height / 2;
if(verbose & DEBUG_IMSIZE)
fprintf(stderr, "pr_sample_2: (%d x %d) -> (%d x %d)\n",
mpr1->mpr_pr.pr_width, mpr1->mpr_pr.pr_height, cols, rows);
/*
* Allocate output image.
*/
if(! pr_check(mpr2, cols, rows, 8))
return (struct pixrect *)NULL;
/*
* Do the sampling.
*/
line_offset = mpr1->mpr_data.md_linebytes;
for(j = 0; j < rows; j++)
{
p0 = P_row(mpr1, j*2);
p1 = p0 + line_offset;
pr = P_row(mpr2, j);
for(er = pr + cols; pr < er; )
{
/*
* Test for all zero.
if(*p0 == 0 && *p1 == 0)
{
*pr++ = 0;
if(pr >= er)
break;
*pr++ = 0;
if(pr >= er)
break;
*pr++ = 0;
if(pr >= er)
break;
*pr++ = 0;
}
else
*/
{
tallies =
tally2[*p0] +
tally2[*p1];
/*
* Highest two bits
*/
*pr++ = (tallies >> 24) + M2F;
if(pr >= er)
break;
*pr++ = (tallies >> 16) + M2F;
if(pr >= er)
break;
*pr++ = (tallies >> 8) + M2F;
if(pr >= er)
break;
/*
* Lowest two bits
*/
*pr++ = tallies + M2F;
}
p0++;
p1++;
}
}
return &mpr2->mpr_pr;
}
/*
* pw_cover:
* Function which writes a pixrect onto a pixwin;
* where there are no src pixels, it writes background colour.
*/
void
pw_cover(dpw, dx, dy, dw, dh, op, spr, sx, sy)
Pixwin *dpw;
int dx, dy, dw, dh;
int op;
Pixrect *spr;
int sx, sy;
{
int aw, ah;
/*
* Handle the left margin.
* If the left margin is less than the width to be painted,
* paint a margin, else paint the whole region and return.
*/
if(sx < 0)
{
if(-sx < dw)
{
pw_writebackground(dpw, dx, dy, -sx, dh, op);
dx -= sx;
sx = 0;
dw += sx;
}
else
{
pw_writebackground(dpw, dx, dy, dw, dh, op);
return;
}
}
/*
* Handle the top margin.
* If the top margin is less thatn the width to be painted,
* paint a margin, else paint the whole region and return.
*/
if(sy < 0)
{
if(-sy < dh)
{
pw_writebackground(dpw, dx, dy, dw, -sy, op);
dy -= sy;
sy = 0;
dh += sy;
}
else
{
pw_writebackground(dpw, dx, dy, dw, dh, op);
return;
}
}
/*
* Handle the right margin.
* aw = available width of source image.
* If available width > 0 paint a margin of dw-aw width,
* otherwise paint the whole region.
*/
aw = spr->pr_width-sx;
if(dw > aw)
{
if(aw > 0)
{
pw_writebackground(dpw, dx+aw, dy, dw-aw, dh, op);
dw = aw;
}
else
{
pw_writebackground(dpw, dx, dy, dw, dh, op);
return;
}
}
/*
* Handle the bottom margin.
* ah = available height of source image.
* If available height > 0 paint a margin of dh-ah height,
* otherwise paint the whole region.
*/
ah = spr->pr_height-sy;
if(dh > ah)
{
if(ah > 0)
{
pw_writebackground(dpw, dx, dy+ah, dw, dh-ah, op);
dh = ah;
}
else
{
pw_writebackground(dpw, dx, dy, dw, dh, op);
return;
}
}
/*
* Paint the image.
*/
pw_write(dpw, dx, dy, dw, dh, op, spr, sx, sy);
}
/*
* pr_rect:
* Draws a box with op and colour as specified.
*/
void
pr_rect(pr, x, y, w, h, t, op, value)
struct pixrect *pr;
int x, y, w, h;
int t;
int op, value;
{
int i;
for(i = 0; i < t; i++)
{
pr_vector(pr, x, y, x+w-1, y, op, value);
pr_vector(pr, x+w-1, y+1, x+w-1, y+h-2, op, value);
pr_vector(pr, x, y+h-1, x+w-1, y+h-1, op, value);
pr_vector(pr, x, y+1, x, y+h-2, op, value);
x += 1;
y += 1;
w -= 2;
h -= 2;
if(w <= 0 || h <= 0)
break;
}
}
/*
* pw_rect:
* Draws a box with op and colour as specified.
*/
void
pw_rect(pw, x, y, w, h, t, op, value)
Pixwin *pw;
int x, y, w, h;
int t;
int op, value;
{
int i;
Rect r;
r.r_left = x;
r.r_top = y;
r.r_width = w;
r.r_height = h;
pw_lock(pw, &r);
for(i = 0; i < t; i++)
{
pw_vector(pw, x, y, x+w-1, y, op, value);
pw_vector(pw, x+w-1, y+1, x+w-1, y+h-2, op, value);
pw_vector(pw, x, y+h-1, x+w-1, y+h-1, op, value);
pw_vector(pw, x, y+1, x, y+h-2, op, value);
x += 1;
y += 1;
w -= 2;
h -= 2;
if(w <= 0 || h <= 0)
break;
}
pw_unlock(pw);
}